#include <eltypes.h>

extern "C" _ELASTOS Int32 __cdecl SWPADD(
    _ELASTOS PInt32 mem,
    _ELASTOS Int32 val)
{
    int tmp1;

    __asm__ __volatile__ ("\n"
        "   mov %0, #0x80000000\n\t"
        "1: swp %0, %0, [%1]\n\t"
        "   cmp %0, #0x80000000\n\t"
        "   beq 1b\n\t"
        "   add  %0, %0, %2\n\t"
        "   cmp %0, #0x80000000\n\t"
        "   addeq %0, %0, %2\n\t"
        "   str  %0, [%1]\n\t"
        : "=&r" (tmp1)
        : "r" (mem), "r"(val)
        : "cc", "memory");

    return tmp1 - val;
}

extern "C" _ELASTOS Int32 __cdecl CMPSWP(
    _ELASTOS PInt32 p,
    _ELASTOS Int32 newval,
    _ELASTOS Int32 oldval)
{
  long result, tmp;

  __asm__ ("\n"
       "0: ldr      %0, [%2]\n\t"
       "   cmp      %0,%4\n\t"
       "   bne      1f\n\t"
       "   swp      %1,%3,[%2]\n\t"
       "   cmp      %0,%1\n\t"
       "   swpne    %0,%1,[%2]\n\t"
       "   bne      0b\n\t"
       "1:"
       : "=&r" (result), "=&r" (tmp)
       : "r" (p), "r" (newval), "r" (oldval)
       : "cc", "memory");

  return result;
}
